/**
 * 度转弧度
 * @param {*} degrees 
 * @returns 
 */
function toRadians(degrees) {
    return degrees * Math.PI / 180;
}

/**
 * 弧度转度
 * @param {*} radians 
 * @returns 
 */
function toDegrees(radians) {
    return radians * 180 / Math.PI;
}

/*
 * 计算两点间角度
 *   startLat：起点纬度
 *   startLng：起点经度
 *   destLat：终点纬度
 *   destLng：终点经度
 * Return 对于正北角度
 */
function bearing(startLat, startLng, destLat, destLng) {
    startLat = this.toRadians(startLat);
    startLng = this.toRadians(startLng);
    destLat = this.toRadians(destLat);
    destLng = this.toRadians(destLng);

    let y = Math.sin(destLng - startLng) * Math.cos(destLat);
    let x = Math.cos(startLat) * Math.sin(destLat) - Math.sin(startLat) * Math.cos(destLat) * Math.cos(destLng - startLng);
    let brng = Math.atan2(y, x);
    let brngDgr = this.toDegrees(brng);
    return (brngDgr + 360) % 360;
}

/**
 * 获取相机参数
 */
function getCameraPamameters() {
    var direction = viewer.camera._direction;
    var x = Cesium.Math.toDegrees(direction.x);
    var y = Cesium.Math.toDegrees(direction.y);
    var z = Cesium.Math.toDegrees(direction.z);
    console.log("_directionX:" + x);
    console.log("_directionY:" + y);
    console.log("_directionZ:" + z);

    //中心点位置
    var rectangle = viewer.camera.computeViewRectangle();
    var west = rectangle.west / Math.PI * 180;
    var north = rectangle.north / Math.PI * 180;
    var east = rectangle.east / Math.PI * 180;
    var south = rectangle.south / Math.PI * 180;
    var centerx = (west + east) / 2;
    var cnetery = (north + south) / 2;
    // 鉴于高德、leaflet获取的边界都是southwest和northeast字段来表示，本例保持一致性
    console.log("centerx:" + centerx);
    console.log("cnetery:" + cnetery);
}

/**
 * 获取相机参数
 */
function getCameraPosition() {
    var position = viewer.camera.position;
    var option = {
        position: position,
        heading: viewer.camera.heading,
        roll: viewer.camera.roll,
        pitch: viewer.camera.pitch
    };
    return option;
}

/**
 * 设置相机的公共方法
 * @param cameraParams
 */
function globleSetCamera(cameraParams, completedCall) {
    if (typeof(cameraParams) == "string") {
        cameraParams = JSON.parse(cameraParams);
    }
    var height = Math.ceil(viewer.camera.positionCartographic.height);

    // viewer.camera.flyTo({
    //     destination: new Cesium.Cartesian3(cameraParams.X, cameraParams.Y, height - 50000),
    //     orientation: {
    //         // heading: cameraParams.Heading,
    //         // pitch: cameraParams.Pitch,
    //         // roll: cameraParams.Roll
    //         heading: Cesium.Math.toRadians(45.0),
    //         pitch: Cesium.Math.toRadians(-90.0),
    //         roll: 0.0
    //     },
    //     duration: cameraParams.Duration / 1000 || 3,
    //     complete: function() {
    viewer.camera.flyTo({
        destination: new Cesium.Cartesian3(cameraParams.X, cameraParams.Y, cameraParams.Z),
        orientation: {
            heading: cameraParams.Heading,
            // pitch: cameraParams.Pitch,
            pitch: cameraParams.Pitch || Cesium.Math.toRadians(-45.0),
            roll: cameraParams.Roll,
            // up: new Cesium.Cartesian3(cameraParams.X, cameraParams.Y, cameraParams.Z + 500),
            // direction: new Cesium.Cartesian3(cameraParams.X, cameraParams.Y, cameraParams.Z)
        },
        duration: cameraParams.Duration / 1000 || 3,
        complete: function() {
            if (completedCall) {
                completedCall();
            }
        }
    });
    //     }
    // });
}

/**
 * 飞行线路中矢量数据渲染整理
 * @param {*} activaties 
 * @returns  [Before,After,Throughout]
 */
function activatiesHandle(activaties) {
    var params = {
        "Before": [],
        "After": [],
        "Throughout": []
    }
    for (var i = 0; i < activaties.length; i++) {
        if (params[activaties[i]["Sequential"]]) {
            for (var j = 0; j < activaties[i]["Entities"].length; j++) {
                activaties[i]["Entities"][j]["Actor"] = activaties[i]["Actor"];
                params[activaties[i]["Sequential"]].push(activaties[i]["Entities"][j]);
            }
        } else if (activaties[i]["Entities"] && activaties[i]["Entities"]["Sequential"] && params[activaties[i]["Entities"]["Sequential"]]) { //Custom
            activaties[i]["Entities"]["Actor"] = activaties[i]["Actor"];
            params[activaties[i]["Entities"]["Sequential"]].push(activaties[i]["Entities"]);
        }
    }
    return params;
}

/**
 * 操作实体对象
 * @param {*} entity 实体  Object
 */
function entitiesHandle(state, params) {
    switch (state) {
        case "1":
            if (params["Before"] && params["Before"].length > 0) {
                for (var i = 0; i < params["Before"].length; i++) {
                    renderEntity(params["Before"][i]);
                }
            }
            if (params["Throughout"] && params["Throughout"].length > 0) {
                for (var i = 0; i < params["Throughout"].length; i++) {
                    if (params["Throughout"][i]["Time"]) {
                        var map = params["Throughout"][i];
                        setTimeout(function() {
                            renderEntity(map);
                        }, params["Throughout"][i]["Time"] + 2000);
                    } else {
                        renderEntity(params["Throughout"][i]);
                    }
                }
            }
            break;
        case "2":
            if (globalParamter[globalPartIndex] && globalParamter[globalPartIndex]["entities"] && globalParamter[globalPartIndex]["entities"]["After"] && globalParamter[globalPartIndex]["entities"]["After"].length > 0) {
                for (var i = 0; i < globalParamter[globalPartIndex]["entities"]["After"].length; i++) {
                    renderEntity(globalParamter[globalPartIndex]["entities"]["After"][i]);
                }
            }
            if (globalParamter[globalPartIndex] && globalParamter[globalPartIndex]["entities"] && globalParamter[globalPartIndex]["entities"]["Throughout"] && globalParamter[globalPartIndex]["entities"]["Throughout"].length > 0) {
                for (var i = 0; i < globalParamter[globalPartIndex]["entities"]["Throughout"].length; i++) {
                    removeDivContainer(globalParamter[globalPartIndex]["entities"]["Throughout"][i]["containerIndex"]);
                }
            }
            break;
        default:
            break;
    }
}

/**
 * 控制场景时钟是否可用
 * @param {*} state 可用状态 boolean
 */
function viewerClockHandle(state) {
    if (state) {
        viewer.clock.canAnimate = true;
        viewer.clock.shouldAnimate = true;
    } else {
        viewer.clock.canAnimate = false;
        viewer.clock.shouldAnimate = false;
    }
}

/**
 * 计算两点间空间位置距离
 * @param {*} sPoint  [x,y,z]
 * @param {*} ePoint  [x,y,z]
 * @returns  distance number
 */
function getGeodesicDistance(sPoint, ePoint) {
    if (sPoint && ePoint) {
        var start = Cesium.Cartographic.fromDegrees(sPoint.X, sPoint.Y, sPoint.Z);
        var end = Cesium.Cartographic.fromDegrees(ePoint.X, ePoint.Y, ePoint.Z);
        var geodesic = new Cesium.EllipsoidGeodesic();
        geodesic.setEndPoints(start, end);
        var distance = distance = Math.sqrt(Math.pow(geodesic.surfaceDistance, 2) + Math.pow(end.height - start.height, 2));
        return parseFloat(distance.toFixed(3));
    } else {
        console.log("参数错误！！");
        return 0;
    }
}

/**
 * 计算数组点位置距离总和
 * @param {*} num 
 * @returns 
 */
function getDistance(num) {
    let alldistance = 0;
    for (let i = 0; i < num.length - 1; i++) {
        alldistance += getGeodesicDistance(num[i], num[i + 1]);
    }
    return alldistance;
}

/**
 * 清除所有定时器
 */
function globalClearTimeout() {
    var highestTimeoutId = setTimeout(";");
    for (var i = 0; i < highestTimeoutId; i++) {
        clearTimeout(i);
    }
}

/**
 * geojson转json
 */
function getMap() {
    var json = InitialParameter("/json/兴趣点.json");
    var features = json.features;
    var pointList = [];
    for (var i = 0; i < features.length; i++) {
        pointList.push({
            X: features[i].properties["X"],
            Y: features[i].properties["Y"],
            NAME: features[i].properties["NAME"]
        });
    }
    console.log(JSON.stringify(pointList));
}

/**
 * 通过参数判断 返回三维球四至范围
 * @param {*} params 
 * @returns 
 */
function getCurrentExtent(params) {
    // 范围对象
    var extent = {};
    var height = Math.ceil(viewer.camera.positionCartographic.height);
    if (params && params.height && height > params.height) {
        return null;
    }
    // 得到当前三维场景
    var scene = viewer.scene;
    // 得到当前三维场景的椭球体
    var ellipsoid = scene.globe.ellipsoid;
    var canvas = scene.canvas;
    // canvas左上角
    var car3_lt = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(0, 0), ellipsoid);
    // canvas右下角
    var car3_rb = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(canvas.width, canvas.height), ellipsoid);
    if (car3_lt && car3_rb) { // 当canvas左上角和右下角全部在椭球体上
        var carto_lt = ellipsoid.cartesianToCartographic(car3_lt);
        var carto_rb = ellipsoid.cartesianToCartographic(car3_rb);
        extent.xmin = Cesium.Math.toDegrees(carto_lt.longitude);
        extent.ymax = Cesium.Math.toDegrees(carto_lt.latitude);
        extent.xmax = Cesium.Math.toDegrees(carto_rb.longitude);
        extent.ymin = Cesium.Math.toDegrees(carto_rb.latitude);
    } else if (!car3_lt && car3_rb) { // 当canvas左上角不在但右下角在椭球体上
        var car3_lt2 = null;
        var yIndex = 0;
        do {
            // 这里每次10像素递加，一是10像素相差不大，二是为了提高程序运行效率
            yIndex <= canvas.height ? yIndex += 10 : canvas.height;
            car3_lt2 = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(0, yIndex), ellipsoid);
        } while (!car3_lt2);
        var carto_lt2 = ellipsoid.cartesianToCartographic(car3_lt2);
        var carto_rb2 = ellipsoid.cartesianToCartographic(car3_rb);
        extent.xmin = Cesium.Math.toDegrees(carto_lt2.longitude);
        extent.ymax = Cesium.Math.toDegrees(carto_lt2.latitude);
        extent.xmax = Cesium.Math.toDegrees(carto_rb2.longitude);
        extent.ymin = Cesium.Math.toDegrees(carto_rb2.latitude);
    }
    // 获取高度
    extent.height = height;
    return extent;
}

var primitiveLayer = {};

function addMSFeatures() {
    if (primitiveLayer["MS"]) {
        primitiveLayer["MS"].setVisible(primitiveLayer["MS"].show);
    } else {
        var labelLayer = new RenderWithPrimitive(viewer, "/json/盟市.json", {
            level: 50000000,
            size: 45,
            color: Cesium.Color.AQUA
        });
        primitiveLayer["MS"] = labelLayer;
    }
}

function addQXQFeatures() {
    if (primitiveLayer["QXQ"]) {
        primitiveLayer["QXQ"].setVisible(primitiveLayer["QXQ"].show);
    } else {
        var labelLayer = new RenderWithPrimitive(viewer, "/json/旗县区.json", {
            level: 300000,
            size: 35,
            color: Cesium.Color.GOLD
        });
        primitiveLayer["QXQ"] = labelLayer;
    }
}

function addJDCFeatures() {
    if (primitiveLayer["JDC"]) {
        primitiveLayer["JDC"].setVisible(primitiveLayer["JDC"].show);
    } else {
        var labelLayer = new RenderWithPrimitive(viewer, "/json/街道村.json", {
            level: 80000,
            size: 30,
            color: Cesium.Color.LAWNGREEN
        });
        primitiveLayer["JDC"] = labelLayer;
    }
}

function addXQDFeatures() {
    if (primitiveLayer["XQD"]) {
        primitiveLayer["XQD"].setVisible(primitiveLayer["XQD"].show);
    } else {
        var labelLayer = new RenderWithPrimitive(viewer, "/json/其他兴趣点.json", {
            level: 20000,
            size: 25,
            color: Cesium.Color.MAGENTA
        });
        primitiveLayer["XQD"] = labelLayer;
    }
}